home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 July / macformat52.iso / mac / Shareware Plus / Developers / YAAF v1.0 alpha 1 / (Sources) / Standard Controls / Scrolling / XGStdScroll.cpp < prev   
Encoding:
C/C++ Source or Header  |  1997-04-24  |  14.8 KB  |  765 lines

  1. /*    XGStdScroll.cpp
  2.  *
  3.  *        The scroll bar handler code
  4.  */
  5.  
  6. /*  YAAF - Yet another application framework
  7.  *  Copyright (C) 1997 William Edward Woody and In Phase Consulting
  8.  *  
  9.  *  This library is free software; you can redistribute it
  10.  *  and/or modify it under the terms of the GNU Library
  11.  *  General Public License as published by the Free Software
  12.  *  Foundation; either version 2 of the License, or any
  13.  *  later version.
  14.  *  
  15.  *  This library is distributed in the hope that it will be
  16.  *  useful, but WITHOUT ANY WARRANTY; without even the implied
  17.  *  warranty of MERCHANTABIILITY or FITNESS FOR A PARTICULAR
  18.  *  PURPOSE. See the GNU Library General Public License for
  19.  *  more details.
  20.  *  
  21.  *  You should have received a copy of the GNU Library General
  22.  *  Public License along with this library; if not, write to the
  23.  *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  24.  *  Boston, MA 02111-1307, USA.
  25.  *  
  26.  *  To contact the author, either e-mail me at
  27.  *  woody@alumni.caltech.edu, or write to us at
  28.  *  
  29.  *          William Edward Woody
  30.  *          In Phase Consulting
  31.  *          1545 Ard Eevin Avenue
  32.  *          Glendale, CA 91202
  33.  */
  34.  
  35. #include <XApplication.h>
  36. #include <XDataUtil.h>
  37. #include <XStdScroll.h>
  38. #include <XWindow.h>
  39. #include <XError.h>
  40.  
  41. /************************************************************************/
  42. /*                                                                        */
  43. /*    Globals                                                                */
  44. /*                                                                        */
  45. /************************************************************************/
  46.  
  47. #if OPT_MACOS == 1
  48. ControlActionUPP    XGStdScroll::gProc = NULL;
  49. #endif
  50.  
  51. /************************************************************************/
  52. /*                                                                        */
  53. /*    Construction/Destruction                                            */
  54. /*                                                                        */
  55. /************************************************************************/
  56.  
  57. /*    XGStdScroll::XGStdScroll
  58.  *
  59.  *        create a push button
  60.  */
  61.  
  62. XGStdScroll::XGStdScroll(XGView *view, XGArgStream &stream) : 
  63.     XGView(view,stream,true)
  64. {
  65.     short min,max,val,page;
  66.     
  67.     page = stream.GetInteger();
  68.     min = stream.GetInteger();
  69.     max = stream.GetInteger();
  70.     val = stream.GetInteger();
  71.     Init(page,min,max,val);
  72. }
  73.  
  74. XGStdScroll::XGStdScroll(XGView *view, XGSScrollInitRecord &i) : 
  75.     XGView(view,i.v,true)
  76. {
  77.     Init(i.page,i.min,i.max,i.val);
  78. }
  79.  
  80. /*    XGStdScroll::~XGStdScroll
  81.  *
  82.  *        Delete me
  83.  */
  84.  
  85. XGStdScroll::~XGStdScroll()
  86. {
  87. #if OPT_MACOS == 1
  88.     if (fControl) ::DisposeControl(fControl);
  89. #endif
  90. }
  91.  
  92. /************************************************************************/
  93. /*                                                                        */
  94. /*    Control management                                                    */
  95. /*                                                                        */
  96. /************************************************************************/
  97.  
  98. /*    XGStdScroll::DoDrawView
  99.  *
  100.  *        Draw my control. This draws the control in a wierd way.
  101.  */
  102.  
  103. void XGStdScroll::DoDrawView(Rect)
  104. {
  105. #if OPT_MACOS == 1
  106.     
  107.     if (fControl && IsActive()) {
  108.         XGDraw draw(this,false);
  109.         ::Draw1Control(fControl);
  110.     } else {
  111.         Rect r;
  112.         XGDraw draw(this);
  113.         
  114.         r = GetContentRect();            // Just erase the rectangle
  115.         FrameRect(&r);
  116.         InsetRect(&r,1,1);
  117.         EraseRect(&r);
  118.     }
  119. #endif
  120. }
  121.  
  122. /*    XGStdScroll::DoActivate
  123.  *
  124.  *        Activate/deactivate scrollbars
  125.  */
  126.  
  127. void XGStdScroll::DoActivate(bool active)
  128. {
  129. #if OPT_MACOS == 1
  130.     XGDraw draw(this,false);
  131.  
  132.     if (fControl) {
  133.         if (active) ::ShowControl(fControl);
  134.         else {
  135.             Rect r;
  136.             
  137.             ::HideControl(fControl);    // reduce flash
  138.             
  139.             r = GetContentRect();
  140.             ViewToGlobal(&r);            // (kludge to keep
  141.             FrameRect(&r);                // the coordinate systems
  142.             InsetRect(&r,1,1);            // correct)
  143.             EraseRect(&r);
  144.         }
  145.     }
  146. #endif
  147.  
  148. #if OPT_WINOS == 1
  149.     #pragma unused(active)
  150. #endif
  151. }
  152.         
  153.  
  154. /*    XGStdScroll::DoMouseDown
  155.  *
  156.  *        Handle mouse click stuff ###TODO
  157.  */
  158.  
  159. bool XGStdScroll::DoMouseDown(Point pt, short)
  160. {
  161. #if OPT_MACOS == 1
  162.     short i;
  163.     XGSScrollEvent e;
  164.     ControlHandle c;
  165.     
  166.     /*
  167.      *    Do the prescroll
  168.      */
  169.     
  170.     if (!fControl) return false;
  171.     
  172.     /*
  173.      *    Handle the track control (in it's own drawing context)
  174.      */
  175.     
  176.     SetControlReference(fControl,(long)(void *)this);
  177.     {
  178.         XGDraw draw(this,false);
  179.         
  180.         // Where in the control?
  181.         ViewToGlobal(&pt);
  182.         i = ::FindControl(pt,GetWindow()->_GetGrafPtr(),&c);
  183.         if (i == kControlIndicatorPart) {
  184.             // In the thumb. Handle thumb scrolling
  185.             e.oldvalue = GetValue();            
  186.             ReceiveDispatch(KEventPreScroll,GetViewID(),(void *)&this);
  187.             i = ::TrackControl(fControl,pt,NULL);
  188.             e.scroll = this;
  189.             ReceiveDispatch(KEventScroll,GetViewID(),(void *)&e);;
  190.         } else {
  191.             // In the rest--handle scrolling bar
  192.             i = ::TrackControl(fControl,pt,gProc);
  193.         }
  194.     }
  195. #endif
  196.  
  197. #if OPT_WINOS == 1
  198.     #pragma unused(pt)
  199. #endif
  200.  
  201.     return false;
  202. }
  203.  
  204. /*    XGStdScroll::DoSizeView
  205.  *
  206.  *        This handles the resize event
  207.  */
  208.  
  209. void XGStdScroll::DoSizeView(void)
  210. {
  211. #if OPT_MACOS == 1
  212.     XGDraw draw(this,false);    
  213.     Rect r;
  214.     
  215.     r = GetContentRect();
  216.     ViewToGlobal(&r);
  217.     if (fControl) ::SizeControl(fControl,r.right-r.left,r.bottom-r.top);
  218. #endif
  219. }
  220.  
  221. /*    XGStdScroll::DoMoveView
  222.  *
  223.  *        Move this view to the new location
  224.  */
  225.  
  226. void XGStdScroll::DoMoveView(void)
  227. {
  228. #if OPT_MACOS == 1
  229.     XGDraw draw(this,false);
  230.     Rect r;
  231.     
  232.     r = GetContentRect();
  233.     ViewToGlobal(&r);
  234.     if (fControl) ::MoveControl(fControl,r.left,r.top);
  235. #endif
  236. }
  237.  
  238. /*    XGStdScroll::ShowView
  239.  *
  240.  *        This also shows the control
  241.  */
  242.  
  243. void XGStdScroll::ShowView()
  244. {
  245.     XGView::ShowView();
  246.     
  247. #if OPT_MACOS == 1
  248.     if (fControl) {
  249.         XGDraw draw(this,false);
  250.         ::ShowControl(fControl);
  251.     }
  252. #endif
  253. }
  254.  
  255. /*    XGStdScroll::HideView
  256.  *
  257.  *        This also hides the control
  258.  */
  259.  
  260. void XGStdScroll::HideView()
  261. {
  262.     XGView::HideView();
  263.     
  264. #if OPT_MACOS == 1
  265.     if (fControl) {
  266.         XGDraw draw(this,false);
  267.         ::HideControl(fControl);
  268.     }
  269. #endif
  270. }
  271.  
  272. /*    XGStdScroll::EnableView
  273.  *
  274.  *        This also enables the control.
  275.  */
  276.  
  277. void XGStdScroll::EnableView()
  278. {
  279.     XGView::EnableView();
  280.     
  281. #if OPT_MACOS == 1
  282.     if (fControl && IsActive()) {
  283.         XGDraw draw(this,false);
  284.         ::HiliteControl(fControl,255);
  285.     }
  286. #endif
  287. }
  288.  
  289. /*    XGStdScroll::DisableView
  290.  *
  291.  *        This also disables the control
  292.  */
  293.  
  294. void XGStdScroll::DisableView()
  295. {
  296.     XGView::DisableView();
  297.     
  298. #if OPT_MACOS == 1
  299.     if (fControl && IsActive()) {
  300.         XGDraw draw(this,false);
  301.         ::HiliteControl(fControl,0);
  302.     }
  303. #endif
  304. }
  305.  
  306. /************************************************************************/
  307. /*                                                                        */
  308. /*    Message Dispatch                                                    */
  309. /*                                                                        */
  310. /************************************************************************/
  311.  
  312. /*    XGStdScroll::ReceiveDispatch
  313.  *
  314.  *        Receive messages. Pass them upwards
  315.  */
  316.  
  317. long XGStdScroll::ReceiveDispatch(long msg, long arg, void *parg)
  318. {
  319. #if OPT_WINOS == 1
  320.     XGSWInternalRecord *w;
  321.     
  322.     if (msg == KEventWInternal) {
  323.         /*
  324.          *    Process the BN_CLICKED command message, turning this
  325.          *    into a KEventButton message.
  326.          */
  327.         
  328.         w = (XGSWInternalRecord *)parg;
  329.         if ((w->msg == WM_HSCROLL) || (w->msg == WM_VSCROLL)) {
  330.             short notify;
  331.             short v = GetValue();
  332.             
  333.             notify = LOWORD(w->wp);
  334.             switch (notify) {
  335.                 case SB_BOTTOM:
  336.                     v = GetMaxValue();
  337.                     break;
  338.                 case SB_LINEDOWN:
  339.                     v++;
  340.                     break;
  341.                 case SB_LINEUP:
  342.                     v--;
  343.                     break;
  344.                 case SB_PAGEDOWN:
  345.                     v += fPageValue;
  346.                     break;
  347.                 case SB_PAGEUP:
  348.                     v -= fPageValue;
  349.                     break;
  350.                 case SB_THUMBPOSITION:
  351.                 case SB_THUMBTRACK:
  352.                     v = HIWORD(w->wp);
  353.                     break;
  354.                 case SB_TOP:
  355.                     v = GetMinValue();
  356.                     break;
  357.                 default:
  358.                     return 0;                    /* Not handled */
  359.             }
  360.             
  361.             // Lazy--just call the SetValue() method
  362.             SetValue(v);
  363.             return 0;
  364.         }
  365.         return 1;
  366.     }
  367. #endif
  368.  
  369.     return XGView::ReceiveDispatch(msg,arg,parg);
  370. }
  371.  
  372. /************************************************************************/
  373. /*                                                                        */
  374. /*    Button Values                                                        */
  375. /*                                                                        */
  376. /************************************************************************/
  377.  
  378. /*    XGStdScroll:GetValue
  379.  *
  380.  *        Get value
  381.  */
  382.  
  383. short XGStdScroll::GetValue(void)
  384. {
  385. #if OPT_MACOS == 1
  386.     return ::GetControlValue(fControl);
  387. #endif
  388.  
  389. #if OPT_WINOS == 1
  390.     SCROLLINFO s;
  391.     
  392.     s.cbSize = sizeof(s);
  393.     s.fMask = SIF_POS;
  394.     ::GetScrollInfo(_GetHWND(),SB_CTL,&s);
  395.     return s.nPos;
  396. #endif
  397. }
  398.  
  399. /*    XGStdScroll::SetValue
  400.  *
  401.  *        Set the value of this thing
  402.  */
  403.  
  404. void XGStdScroll::SetValue(short x)
  405. {
  406.     XGSScrollEvent e;
  407.     short ov,nv;
  408.     
  409.     // Find the new value (if it changes)
  410.     ov = GetValue();
  411.     nv = x;
  412.     if (nv < GetMinValue()) nv = GetMinValue();
  413.     if (nv > GetMaxValue()) nv = GetMaxValue();
  414.     if (nv == ov) return;            /* Value doesn't change */
  415.  
  416.     // Send the change value messages
  417.     ReceiveDispatch(KEventPreScroll,GetViewID(),(void *)this);
  418.     
  419.     // Now change the value
  420. #if OPT_MACOS == 1
  421.     {
  422.         XGDraw draw(this,false);        // make sure set up right
  423.         ::SetControlValue(fControl,nv);
  424.     }
  425. #endif
  426.  
  427. #if OPT_WINOS == 1
  428.     SCROLLINFO s;
  429.     
  430.     s.cbSize = sizeof(s);
  431.     s.fMask = SIF_POS;
  432.     s.nPos = nv;
  433.     ::SetScrollInfo(_GetHWND(),SB_CTL,&s,true);
  434. #endif
  435.  
  436.     // Send the new value message
  437.     e.oldvalue = ov;
  438.     e.scroll = this;
  439.     ReceiveDispatch(KEventScroll,GetViewID(),(void *)&e);
  440. }
  441.  
  442.  
  443. /*    XGStdScroll:GetMinValue
  444.  *
  445.  *        Get value
  446.  */
  447.  
  448. short XGStdScroll::GetMinValue(void)
  449. {
  450. #if OPT_MACOS == 1
  451.     return ::GetControlMinimum(fControl);
  452. #endif
  453.  
  454. #if OPT_WINOS == 1
  455.     SCROLLINFO s;
  456.     
  457.     s.cbSize = sizeof(s);
  458.     s.fMask = SIF_RANGE;
  459.     ::GetScrollInfo(_GetHWND(),SB_CTL,&s);
  460.     return s.nMin;
  461. #endif
  462. }
  463.  
  464. /*    XGStdScroll::SetMinValue
  465.  *
  466.  *        Set the value of this thing
  467.  */
  468.  
  469. void XGStdScroll::SetMinValue(short x)
  470. {
  471.     XGSScrollEvent e;
  472.     short ov,nv;
  473.     
  474.     // Find the new value (if it changes)
  475.     ov = GetValue();
  476.     nv = ov;
  477.     if (nv < x) nv = x;
  478.  
  479.     // If the value changed, send the change value messages
  480.     if (nv != ov) ReceiveDispatch(KEventPreScroll,GetViewID(),(void *)this);
  481.     
  482.     // Now change the value
  483. #if OPT_MACOS == 1
  484.     {
  485.         XGDraw draw(this,false);        // make sure set up right
  486.         ::SetControlMinimum(fControl,x);
  487.     }
  488. #endif
  489.  
  490. #if OPT_WINOS == 1
  491.     SCROLLINFO s;
  492.     
  493.     s.cbSize = sizeof(s);
  494.     s.fMask = SIF_RANGE;
  495.     ::GetScrollInfo(_GetHWND(),SB_CTL,&s);
  496.     s.nMin = x;
  497.     ::SetScrollInfo(_GetHWND(),SB_CTL,&s,true);
  498. #endif
  499.  
  500.     // If the value changed, send the new value message
  501.     if (nv != ov) {
  502.         e.oldvalue = ov;
  503.         e.scroll = this;
  504.         ReceiveDispatch(KEventScroll,GetViewID(),(void *)&e);
  505.     }    
  506. }
  507.  
  508.  
  509. /*    XGStdScroll:GetMaxValue
  510.  *
  511.  *        Get value
  512.  */
  513.  
  514. short XGStdScroll::GetMaxValue(void)
  515. {
  516. #if OPT_MACOS == 1
  517.     return ::GetControlMaximum(fControl);
  518. #endif
  519.  
  520. #if OPT_WINOS == 1
  521.     SCROLLINFO s;
  522.     
  523.     s.cbSize = sizeof(s);
  524.     s.fMask = SIF_RANGE;
  525.     ::GetScrollInfo(_GetHWND(),SB_CTL,&s);
  526.     return s.nMax;
  527. #endif
  528. }
  529.  
  530. /*    XGStdScroll::SetMaxValue
  531.  *
  532.  *        Set the value of this thing
  533.  */
  534.  
  535. void XGStdScroll::SetMaxValue(short x)
  536. {
  537.     XGSScrollEvent e;
  538.     short ov,nv;
  539.     
  540.     // Find the new value (if it changes)
  541.     ov = GetValue();
  542.     nv = ov;
  543.     if (nv > x) nv = x;
  544.  
  545.     // If the value changed, send the change value messages
  546.     if (nv != ov) ReceiveDispatch(KEventPreScroll,GetViewID(),(void *)this);
  547.     
  548.     // Now change the value
  549. #if OPT_MACOS == 1
  550.     {
  551.         XGDraw draw(this,false);        // make sure set up right
  552.         ::SetControlMaximum(fControl,x);
  553.     }
  554. #endif
  555.  
  556. #if OPT_WINOS == 1
  557.     SCROLLINFO s;
  558.     
  559.     s.cbSize = sizeof(s);
  560.     s.fMask = SIF_PAGE | SIF_RANGE;
  561.     ::GetScrollInfo(_GetHWND(),SB_CTL,&s);
  562.     s.nMax = x;
  563.     if (s.nPage > 0) s.nMax += s.nPage - 1;
  564.     ::SetScrollInfo(_GetHWND(),SB_CTL,&s,true);
  565. #endif
  566.  
  567.     // If the value changed, send the new value message
  568.     if (nv != ov) {
  569.         e.oldvalue = ov;
  570.         e.scroll = this;
  571.         ReceiveDispatch(KEventScroll,GetViewID(),(void *)&e);
  572.     }    
  573. }
  574.  
  575. /*    XGStdScroll:GetPageValue
  576.  *
  577.  *        Get value
  578.  */
  579.  
  580. short XGStdScroll::GetPageValue(void)
  581. {
  582.     return fPageValue;
  583. }
  584.  
  585. /*    XGStdScroll::SetPageValue
  586.  *
  587.  *        Set the value of this thing
  588.  */
  589.  
  590. void XGStdScroll::SetPageValue(short x)
  591. {
  592.     fPageValue = x;
  593.  
  594. #if OPT_WINOS == 1
  595.     SCROLLINFO s;
  596.     
  597.     s.cbSize = sizeof(s);
  598.     s.fMask = SIF_PAGE | SIF_RANGE;
  599.     ::GetScrollInfo(_GetHWND(),SB_CTL,&s);
  600.     
  601.     /* Adjust min/max in page value */
  602.     if (s.nPage > 0) s.nMax = s.nMax - s.nPage + 1;    /* Actual max */
  603.     if (x > 0) s.nMax = s.nMax + x - 1;
  604.  
  605.     s.nPage = x;
  606.     ::SetScrollInfo(_GetHWND(),SB_CTL,&s,true);
  607. #endif
  608. }
  609.  
  610. /************************************************************************/
  611. /*                                                                        */
  612. /*    Action Proc Stuff                                                    */
  613. /*                                                                        */
  614. /************************************************************************/
  615.  
  616. #if OPT_MACOS == 1
  617.  
  618. /*    XGStdScroll::ActionProc
  619.  *
  620.  *        The action proc for scrolling the scrollbar
  621.  */
  622.  
  623. pascal void XGStdScroll::ActionProc(ControlHandle c, short part)
  624. {
  625.     XGStdScroll *s = (XGStdScroll *)GetControlReference(c);
  626.     short ov,nv;
  627.     short min,max;
  628.     XGSScrollEvent e;
  629.     
  630.     ov = s->GetValue();
  631.     min = s->GetMinValue();
  632.     max = s->GetMaxValue();
  633.     
  634.     switch (part) {
  635.         default:
  636.             return;
  637.         
  638.         case kControlUpButtonPart:
  639.             nv = ov - 1;
  640.             break;
  641.         
  642.         case kControlDownButtonPart:
  643.             nv = ov + 1;
  644.             break;
  645.         
  646.         case kControlPageUpPart:
  647.             nv = ov - s->GetPageValue();
  648.             break;
  649.         
  650.         case kControlPageDownPart:
  651.             nv = ov + s->GetPageValue();
  652.             break;
  653.     }
  654.     
  655.     if (nv < min) nv = min;
  656.     if (nv > max) nv = max;
  657.     if (nv == ov) return;                /* No change */
  658.     
  659.     /*
  660.      *    The scrollbar has changed. This sends the appropriate
  661.      *    messages
  662.      */
  663.     
  664.     e.oldvalue = ov;
  665.     e.scroll = s;
  666.     s->ReceiveDispatch(KEventPreScroll,s->GetViewID(),(void *)&s);
  667.     ::SetControlValue(s->fControl,nv);    /* Change directly */
  668.     s->ReceiveDispatch(KEventScroll,s->GetViewID(),(void *)&e);
  669. }
  670.  
  671. #endif
  672.  
  673. /************************************************************************/
  674. /*                                                                        */
  675. /*    Construction                                                        */
  676. /*                                                                        */
  677. /************************************************************************/
  678.  
  679. /*    XGStdScroll::Init
  680.  *
  681.  *        Initialization central
  682.  */
  683.  
  684. void XGStdScroll::Init(short page, short min, short max, short val)
  685. {
  686.     fPageValue = page;
  687.     
  688. #if OPT_MACOS == 1
  689.     XGDraw draw(this,false);
  690.     Rect r;
  691.     
  692.     /*
  693.      *    Create the control at this location
  694.      */
  695.     
  696.     r = GetContentRect();
  697.     ViewToGlobal(&r);
  698.     fControl = NewControl(GetWindow()->_GetGrafPtr(),        // window owner
  699.                           &r,                                // where
  700.                           "\p",                                // title
  701.                           true,                                // visible
  702.                           val,                                // initial value
  703.                           min,                                // min value
  704.                           max,                                // max value
  705.                           scrollBarProc,                    // push button proc
  706.                           0);                                // refcon
  707.     if (fControl == NULL) {
  708.         throw XPostError("Unable to make scroll bar");
  709.     }
  710.     
  711.     if (gProc == NULL) gProc = NewControlActionProc(ActionProc);
  712. #endif
  713.  
  714. #if OPT_WINOS == 1
  715.     Rect r;
  716.     HWND w;
  717.     long f;
  718.     
  719.     /*
  720.      *    Get the location of the control in the parent's coordinate
  721.      *    system
  722.      */
  723.      
  724.     r = GetContentRect();
  725.     if (GetParent()) {
  726.         ViewToGlobal(&r);
  727.         GetParent()->GlobalToView(&r);
  728.     }
  729.     
  730.     /*
  731.      *    Create the control window
  732.      */
  733.     
  734.     if (r.right - r.left > r.bottom - r.top) f = SBS_HORZ;
  735.     else f = SBS_VERT;
  736.     
  737.     w = CreateWindow("SCROLLBAR",                // control class
  738.                      "",                        // control title
  739.                      WS_CHILD | f,                // control window flags
  740.                      r.left,
  741.                      r.top,
  742.                      r.right-r.left,
  743.                      r.bottom-r.top,            // control location
  744.                      GetParent()->_GetHWND(),    // container window
  745.                      NULL,                        // no menu
  746.                      _GInstance,                // My app instance
  747.                      NULL);                        // no additional args
  748.     if (w == NULL) {
  749.         throw XPostError("Unable to make scroll bar");
  750.     }
  751.  
  752.     _SetHWND(w);                                // set me as the window
  753.     SetProp(w,_GViewClass,(HANDLE)this);
  754.  
  755.     SetMinValue(min);                            // scroll bar parameters
  756.     SetMaxValue(max);
  757.     SetValue(val);
  758.     SetPageValue(fPageValue);
  759.  
  760.     if (IsVisible()) ShowWindow(w,SW_SHOW);
  761.     EnableWindow(w,IsEnabled());                // set me up
  762. #endif
  763. }
  764.  
  765.